/*
 *  header.c
 *  oE6
 *
 *  Created by Tony Million on 12/12/2008.
 *  Copyright 2008 Tony Million. All rights reserved.
 *
 */

#include "header.h"
#include "bitstream.h"
#include <stdio.h>

#define HDRMAIN_BITS	0xfffffc00			// 1111 1111 1111 1111 1111 1100 0000 0000
#define MPEG_BITS		0x00180000			// 0000 0000 0001 1000 0000 0000 0000 0000
#define LAYER_BITS		0x00060000			// 0000 0000 0000 0110 0000 0000 0000 0000
#define CRC_BIT			0x00010000			// 0000 0000 0000 0001 0000 0000 0000 0000
#define BITRATE_BITS	0x0000f000			// 0000 0000 0000 0000 ffff 0000 0000 0000
#define SAMP_BITS		0x00000C00			// 0000 0000 0000 0000 0000 1100 0000 0000 
#define PADING_BIT		0x00000200			// 0000 0000 0000 0000 0000 0010 0000 0000 
#define PRIVATE_BIT		0x00000100			// 0000 0000 0000 0000 0000 0001 0000 0000 
#define MODE_BITS		0x000000C0			// 0000 0000 0000 0000 0000 0000 1100 0000 
#define MODEEXT_BITS	0x00000030			// 0000 0000 0000 0000 0000 0000 0011 0000 
#define COPYRIGHT_BIT	0x00000008			// 0000 0000 0000 0000 0000 0000 0000 1000 
#define ORIGINAL_BIT	0x00000004			// 0000 0000 0000 0000 0000 0000 0000 0100 
#define EMPHASIS_BITS	0x00000003			// 0000 0000 0000 0000 0000 0000 0000 0011 

#define CHECK_BITS		0xfffe0c00

#define MPEG_BITS_1		0x00180000
#define MPEG_BITS_2		0x00100000
#define MPEG_BITS_25	0x00000000

#define LAYER_BITS_1	0x00060000
#define LAYER_BITS_2	0x00040000
#define LAYER_BITS_3	0x00020000

#define MPEGVERSION_BITSHIFT	19
#define LAYER_BITSHIFT			17
#define BITRATE_BITSHIFT		12
#define SAMPLERATE_BITSHIFT		10
#define MODE_BITSHIFT			6
#define MODE_EXT_BITSHIFT		4


const unsigned long BitRates[2][3][16] = 
{
	{
		{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0},
		{0 /*free format*/, 32000, 48000, 56000,  64000,  80000,  96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0},
		{0 /*free format*/, 32000, 40000, 48000,  56000,  64000,  80000,  96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}
	},
	{
		{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000, 224000, 256000, 0},
		{0 /*free format*/,  8000, 16000, 24000, 32000, 40000, 48000,  56000,  64000,  80000,  96000, 112000, 128000, 144000, 160000, 0},
		{0 /*free format*/,  8000, 16000, 24000, 32000, 40000, 48000,  56000,  64000,  80000,  96000, 112000, 128000, 144000, 160000, 0}
	},
};


const unsigned long SampleRates[3][3] = 
{
	{
		44100, 48000, 32000
	},
	{
		22050, 24000, 16000
	},
	{
		11025, 12000, 8000
	}
};



int decodeHeader(unsigned char * bytes, header * head)
{
	bitstream bs;
	
	bsinit(&bs, bytes, 4);
	
	if((bsgetbits(&bs, 12) & 0xfff) != 0xfff)
		return 0;
	
	// read the MPEG version
	if(bsgetbits(&bs, 1))
	{
		head->MpegVersion = MPEG1;
	}
	else
	{
		head->MpegVersion = MPEG2;
	}
	
	// get layer, anything other than layer3 is invalid
	switch(bsgetbits(&bs, 2))
	{
		case 1:
			head->Layer = LAYER3;
			break;
		default:
			return 0;
	}
	
	// read the CRC bit (we use this later
	head->CRCPresent = bsgetbits(&bs, 1);
	
	
	// read the bitrate index, and get the bitrate out of the array
	head->BitrateIndex = bsgetbits(&bs, 4);
	if((head->BitrateIndex == 0xff) || (head->BitrateIndex == 0))
	{
		// 16 and 0 are invalid
		// technically 0 isn't invalid, but we can't do it atm
		return 0;
	}
	head->Bitrate = BitRates[head->MpegVersion][head->Layer][head->BitrateIndex];
	
	
	// read the sample rate index, and grab it
	head->SampleRateIndex = bsgetbits(&bs, 2);
	if(head->SampleRateIndex == 0x03)
	{
		// 3 is invalid and is used as a check
		return 0;
	}
	head->SampleRate = SampleRates[head->MpegVersion][head->SampleRateIndex];
	
	// this bit means there is an extra byte on the end of the frame (you'll see later)
	head->PaddingBit = bsgetbits(&bs, 1);
	
	// lame copyright bit....
	head->PrivateBit = bsgetbits(&bs, 1);
	
	head->Mode				= bsgetbits(&bs, 2);
	head->Mode_Extension	= bsgetbits(&bs, 2);
	
	if(head->Mode == MODE_MONO)
	{
		head->Channels = 1;
	}
	else
	{
		head->Channels = 2;
	}
	
	head->Copyright			= bsgetbits(&bs, 1);
	head->Original			= bsgetbits(&bs, 1);
	
	head->Emphasis			= bsgetbits(&bs, 2);
	if(head->Emphasis == EMPH_RESERVED)
		return 0;
	
	
	if(head->MpegVersion == MPEG1)
	{
		if(head->Channels==1)
			head->SideInfoSize = 17;
		else
			head->SideInfoSize = 32;
	}
	else
	{
		if(head->Channels==1)
			head->SideInfoSize = 9;
		else
			head->SideInfoSize = 17;
	}
	
	int base = 144;   
	if(head->MpegVersion != MPEG1)
		base = 72;
	   
	head->AudioDataSize	= ((base * head->Bitrate) / head->SampleRate);
	
	if(head->PaddingBit)
	   head->AudioDataSize++;

	head->AudioDataSize -= 4;		// for the header
	
	if(head->CRCPresent)
		head->AudioDataSize -= 2;
		
	head->AudioDataSize -= head->SideInfoSize;

	   
	
	return 1;
}

/*
 unsigned long header =	(unsigned long)bytes[0] << 24 | 
 (unsigned long)bytes[1] << 16 |
 (unsigned long)bytes[2] <<8   |
 (unsigned long)bytes[3];
 
 if((header & 0xfff00000) != 0xfff00000)
 {
 //printf("INvalid header\r\n");
 //fflush(stdout);
 return 0;
 }
 
 // work out mpeg version
 if((header & MPEG_BITS) == MPEG_BITS_1)
 {
 head->MpegVersion = MPEG1;
 }
 else
 {
 head->MpegVersion = MPEG2;
 }
 
 // work out layer
 
 
 //work out mode
 if(((header & MODE_BITS) >> MODE_BITSHIFT) == MODE_MONO)
 {
 head->Channels = 1;
 }
 else
 {
 head->Channels = 2;
 }	
 
 int layer = ((header & LAYER_BITS) >> LAYER_BITSHIFT);
 
 switch(layer)
 {
 case 1:
 head->Layer = LAYER3;
 break;	
 
 default:
 {
 return 0;
 }
 break;			
 }
 
 head->BitrateIndex = ((header & BITRATE_BITS) >> BITRATE_BITSHIFT);
 if((head->BitrateIndex == 0xff) || (head->BitrateIndex == 0))
 {
 return 0;
 }
 head->Bitrate = BitRates[head->MpegVersion][head->Layer][head->BitrateIndex];
 
 
 
 head->SampleRateIndex = ((header & SAMP_BITS) >> SAMPLERATE_BITSHIFT);
 if(head->SampleRateIndex == 0x03)
 {
 return 0;
 }
 head->SampleRate = SampleRates[head->MpegVersion][head->SampleRateIndex];
 
 
 
 if(header & PADING_BIT)
 {
 head->PaddingBit = 1;
 }
 else
 {
 head->PaddingBit = 0;		
 }
*/